package com.lambkit.db.hutool;

import cn.hutool.db.Entity;
import cn.hutool.db.Page;
import cn.hutool.db.sql.SqlBuilder;
import com.lambkit.db.*;

import java.sql.SQLException;
import java.util.List;

/**
 * @author yangyong(孤竹行)
 */
public class HutoolModelDao<M extends RowModel<M>> extends HutoolDbOpt<M, PageData<M>> implements IRowDao<M> {
    private Class<M> modelClass;

    public HutoolModelDao(HutoolDbOpt db, Class<M> modelClass)  {
        super(db.getDb(), db.getDialect());
        this.modelClass = modelClass;
    }

    public Entity toEntity(M row) {
        Entity entity = Entity.create(row.tableName());
        entity.setFieldNames(row.columnNames());
        entity.putAll(row.toMap());
        return entity;
    }

    @Override
    public PageData<M> paginate(Integer pageNumber, Integer pageSize, Sql sqlPara) {
        Page page = new Page(pageNumber, pageSize);
        try {
            SqlBuilder sqlBuilder = SqlBuilder.of(sqlPara.getSql()).addParams(sqlPara.getPara());
            int total = (int) getDb().count(sqlBuilder);
            ModelPageHandler handler = new ModelPageHandler<M>(modelClass, true, pageNumber, pageSize, total);
            return (PageData<M>) getDb().page(sqlBuilder, page, handler);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public List<M> find(String sql, Object... paras) {
        try {
            return getDb().query(sql, new ModelListHandler<M>(modelClass, true), paras);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public M findFirst(String sql, Object... paras) {
        try {
            return getDb().query(sql, new ModelHandler<M>(modelClass, true), paras);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}
